// Ch8_3.cpp : Initialization functions

// CH8_3.cpp
// by Charles Mc Auley
// "Programming AutoCAD 2000 with ObjectARX"
//
// In this application we demonstrate how to add/retrieve
// XRecords to the Named Objects Dictionary. These XRecords
// are associated to the entity by an entities handle name.
//
/////////////////////////////////////////////////////////


#include "StdAfx.h"
#include "StdArx.h"
#include "resource.h"
#include "geassign.h"

HINSTANCE _hdllInstance =NULL ;

// This command registers an ARX command.
void AddCommand(const char* cmdGroup, const char* cmdInt, const char* cmdLoc,
				const int cmdFlags, const AcRxFunctionPtr cmdProc, const int idLocal = -1);

// NOTE: DO NOT edit the following lines.
//{{AFX_ARX_MSG
void InitApplication();
void UnloadApplication();
//}}AFX_ARX_MSG

// NOTE: DO NOT edit the following lines.
//{{AFX_ARX_ADDIN_FUNCS
//}}AFX_ARX_ADDIN_FUNCS

/////////////////////////////////////////////////////////////////////////////
// DLL Entry Point
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
	if (dwReason == DLL_PROCESS_ATTACH)
	{
        _hdllInstance = hInstance;
	} else if (dwReason == DLL_PROCESS_DETACH) {
	}
	return TRUE;    // ok
}



/////////////////////////////////////////////////////////////////////////////
// ObjectARX EntryPoint
extern "C" AcRx::AppRetCode 
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
	switch (msg) {
	case AcRx::kInitAppMsg:
		// Comment out the following line if your
		// application should be locked into memory
		acrxDynamicLinker->unlockApplication(pkt);
		acrxDynamicLinker->registerAppMDIAware(pkt);
		InitApplication();
		break;
	case AcRx::kUnloadAppMsg:
		UnloadApplication();
		break;
	}
	return AcRx::kRetOK;
}


// Init this application. Register your
// commands, reactors...
void InitApplication()
{
	// NOTE: DO NOT edit the following lines.
	//{{AFX_ARX_INIT
	AddCommand("CH8_APPS", "WINDO", "WINDO", ACRX_CMD_MODAL, windo);
	AddCommand("CH8_APPS", "PWI", "PWI", ACRX_CMD_MODAL, pickWindowInfo);
	//}}AFX_ARX_INIT

	// TODO: add your initialization functions
	acutPrintf("Enter \"WINDO\" to execute the application.\n");
	acutPrintf("Enter \"PWI\" to Pick Window Information.\n");
}

// Unload this application. Unregister all objects
// registered in InitApplication.
void UnloadApplication()
{
	// NOTE: DO NOT edit the following lines.
	//{{AFX_ARX_EXIT
	acedRegCmds->removeGroup("CH8_APPS");
	//}}AFX_ARX_EXIT

	// TODO: clean up your application
	acutPrintf("%s%s", "Goodbye\n", "Removing command group \"CH8_APPS\"\n");
}

// This functions registers an ARX command.
// It can be used to read the localized command name
// from a string table stored in the resources.
void AddCommand(const char* cmdGroup, const char* cmdInt, const char* cmdLoc,
				const int cmdFlags, const AcRxFunctionPtr cmdProc, const int idLocal)
{
	char cmdLocRes[65];

	// If idLocal is not -1, it's treated as an ID for
	// a string stored in the resources.
	if (idLocal != -1) {

		// Load strings from the string table and register the command.
		::LoadString(_hdllInstance, idLocal, cmdLocRes, 64);
		acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLocRes, cmdFlags, cmdProc);

	} else
		// idLocal is -1, so the 'hard coded'
		// localized function name is used.
		acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLoc, cmdFlags, cmdProc);
}


// User defined support functions called from
// windo(), see Ch8_3Commands.cpp
Adesk::Boolean getWindowInputParameters(RectWindow* pWindow)
{
	AcGePoint2d startPt;
	AcGePoint3d pickPt;
	int rows = 1, cols = 1;
	double windLength, windHeight;
	int rc;	// Return code

	acedInitGet(RSG_NONULL + RSG_NONEG + RSG_NOZERO, NULL);
	rc = acedGetReal("\nWindow Height: ", &windHeight);

	if(rc == RTCAN || rc == RTERROR)
	{
		return Adesk::kFalse;
	}

	acedInitGet(RSG_NONULL + RSG_NONEG + RSG_NOZERO, NULL);
	rc = acedGetReal("\nWindow Length: ", &windLength);

	if(rc == RTCAN || rc == RTERROR)
	{
		return Adesk::kFalse;
	}

	acedInitGet(RSG_NOZERO + RSG_NONEG, NULL);
	rc = acedGetInt("\nNumber of window columns <Return> for none: ", &cols);
	
	if(rc == RTCAN || rc == RTERROR)
	{
		return Adesk::kFalse;
	}

	acedInitGet(RSG_NOZERO + RSG_NONEG, NULL);
	rc = acedGetInt("\nNumber of window rows <Return> for none: ", &rows);
	
	if(rc == RTCAN || rc == RTERROR)
	{
		return Adesk::kFalse;
	}


	acedInitGet(NULL, NULL);
	rc = acedGetPoint(NULL, "\nPick lower left window insertion point <Return for (0,0)>: ", 
				asDblArray(pickPt));

	
	switch(rc)
	{
		case RTCAN:
		case RTERROR:
			return Adesk::kFalse;
		break;

		case RTNONE:
			startPt.x = 0;
			startPt.y = 0;
		break;

		case RTNORM:
			startPt.x = pickPt.x;
			startPt.y = pickPt.y;
		break;
	}

	// Fill out the window class object
	// with the input values

	pWindow->setWindowLength(windLength);
	pWindow->setWindowHeight(windHeight);
	pWindow->setWindowCols(cols);
	pWindow->setWindowRows(rows);
	pWindow->setWindowStartPoint(startPt);

	return Adesk::kTrue;
}


Adesk::Boolean getModelSpaceRecord(AcDbBlockTableRecord*& pBlkTableRecord)
{
	AcDbDatabase *pCurDb;
	AcDbBlockTable *pBlkTable;
	Acad::ErrorStatus es;

	pCurDb = acdbHostApplicationServices()->workingDatabase();

	es = pCurDb->getBlockTable(pBlkTable, AcDb::kForRead);
	if(es != Acad::eOk)
	{
		acutPrintf("\nFailed to open Block Table for a read operation.");
		return Adesk::kFalse;
	}

	es = pBlkTable->getAt(ACDB_MODEL_SPACE, pBlkTableRecord, AcDb::kForWrite);
	if(es != Acad::eOk)
	{
		acutPrintf("\nFailed to open MODEL SPACE for a write operation.");
		pBlkTable->close();
		return Adesk::kFalse;
	}

	// We don't need the block table anymore so we can close it.
	pBlkTable->close();

	return Adesk::kTrue;
}

